#include <stdio.h>
#include <stdlib.h>
#include "dataqueue.h"

Cthread_canworkqueue *cansendqueue;     //can发送工作队列
Cthread_uartworkqueue *uartsendqueue;   //uart发送工作队列
Cthread_ethworkqueue *ethsendqueue;     //eth发送工作队列
Cthread_udpworkqueue *udpsendqueue;     //udp发送工作队列

Cthread_canworkqueue *canrecvqueue;     //can接收工作队列
Cthread_uartworkqueue *uartrecvqueue;   //uart接收工作队列
Cthread_ethworkqueue *ethrecvqueue;     //eth接收工作队列


/**
 * 向串口队列添加待处理的任务
 * 既可以向 发送队列添加，也可以向接收队列添加（通过参数 uartqueue 实现不同队列添加）
 * */
void can_add_task(Cthread_canworkqueue *canqueue,const CANTxMsg_t *msg)
{
    int i;
    //printf("Add a commond to queue!\n");
    Cthread_cantask *new_task = (Cthread_cantask *) malloc (sizeof (Cthread_cantask));//构造一个新任务, 在发送线程释放
    
    new_task->id = msg->CANTxStruct.StdId;
    
    new_task->len = msg->CANTxStruct.DLC;
    for(i=0; i<msg->CANTxStruct.DLC ; i++){
        new_task->data[i] = msg->CANTxStruct.Data[i];
        //printf("%02x ",msg->CANTxStruct.Data[i]); //DBUG
    }
    //printf("\n");   //DBUG

    new_task->next = NULL;

    pthread_mutex_lock (&(canqueue->queue_lock));
    /*将任务加入到等待队列中*/
    Cthread_cantask *member = canqueue->queue_head;
    if (member != NULL)
    {
        while (member->next != NULL)        //while循环查找任务末尾
            member = member->next;
        member->next = new_task;
    }
    else
    {
        canqueue->queue_head = new_task;
    }
    canqueue->cur_queue_size++;
    pthread_mutex_unlock(&(canqueue->queue_lock)); //工作队列数量++
    pthread_cond_signal(&(canqueue->queue_ready)); //通知线程ok 

}


/**
 * 向串口队列添加待处理的任务
 * 既可以向 发送队列添加，也可以向接收队列添加（通过参数 uartqueue 实现不同队列添加）
 * */
void uart_add_task(Cthread_uartworkqueue *uartqueue,char *buff) 
{
    int i;
    Cthread_uarttask *new_task = (Cthread_uarttask *) malloc (sizeof (Cthread_uarttask));//构造一个新任务
    for(i = 0; i < UART_CMD_LENGTH; i++ ){
        new_task->data[i]= buff[i];
    }
    new_task->next = NULL;

    pthread_mutex_lock (&(uartqueue->queue_lock));
    /*将任务加入到等待队列中*/
    Cthread_uarttask *member = uartqueue->queue_head;
    if (member != NULL)
    {
        while (member->next != NULL)        //while循环查找任务末尾
            member = member->next;
        member->next = new_task;
    }
    else    
    {
        uartqueue->queue_head = new_task;
    }
    uartqueue->cur_queue_size++;
    
    pthread_mutex_unlock (&(uartqueue->queue_lock)); //工作队列数量++
    pthread_cond_signal(&(uartqueue->queue_ready)); //通知线程ok
    //printf("pthread_cont signal\n");

}


/**
 * 向网络通信队列添加待处理的任务
 * 既可以向 发送队列添加，也可以向接收队列添加（通过参数 ethqueue 实现不同队列添加）
 * */
void eth_add_task(Cthread_ethworkqueue *ethqueue,char *buff)
{
    uint8_t i;

    Cthread_ethtask *new_task = (Cthread_ethtask *) malloc (sizeof (Cthread_ethtask));//构造一个新任务
    
    //填充数据
    for(i = 0; i < ETH_CMD_LENGTH; i++){
        new_task->data[i]= buff[i];
    }    
    new_task->next = NULL;
    pthread_mutex_lock (&(ethqueue->queue_lock));

    /*将任务加入到等待队列中*/
    Cthread_ethtask *member = ethqueue->queue_head;
    if (member != NULL)
    {
        while (member->next != NULL)        //while循环查找任务末尾
            member = member->next;
        member->next = new_task;
    }
    else
    {
        ethqueue->queue_head = new_task;
    }

    ethqueue->cur_queue_size++;
    pthread_mutex_unlock (&(ethqueue->queue_lock)); //工作队列数量++
    pthread_cond_signal (&(ethqueue->queue_ready)); //通知线程ok

}

void udp_add_task(uint8_t destip,uint16_t destport, const char *buff, char len)
{
    uint8_t i;

    Cthread_udptask *new_task = (Cthread_udptask *) malloc (sizeof (Cthread_udptask));//构造一个新任务
    
    //填充数据
    for(i = 0; i < len; i++){
        new_task->data[i]= buff[i];
    }  
    new_task->destip = destip;      //远端ip
    new_task->destport = destport;  //远端端口号
    new_task->len = len; 
    new_task->next = NULL;

    pthread_mutex_lock (&(udpsendqueue->queue_lock));

    /*将任务加入到等待队列中*/
    Cthread_udptask *member = udpsendqueue->queue_head;
    if (member != NULL)
    {
        while (member->next != NULL)        //while循环查找任务末尾
            member = member->next;
        member->next = new_task;
    }
    else
    {
        udpsendqueue->queue_head = new_task;
    }
    udpsendqueue->cur_queue_size++;
    pthread_mutex_unlock (&(udpsendqueue->queue_lock)); //工作队列数量++
    pthread_cond_signal (&(udpsendqueue->queue_ready)); //通知线程ok

}



/** 
  * canbus发送初始化
  * 
  * 返回值：工作队列结构体指针
  **/
Cthread_canworkqueue *canworkqueue_init()
{

    Cthread_canworkqueue *queue = (Cthread_canworkqueue *) malloc (sizeof (Cthread_canworkqueue)); //为工作队列分配内存
    pthread_mutex_init(&(queue->queue_lock), NULL);             //初始化互斥锁
    pthread_cond_init(&(queue->queue_ready), NULL);             //初始化条件变量
    queue->queue_head = NULL;                                    //初始化工作队列头
    queue->cur_queue_size = 0;
    queue->queuethreadid =(pthread_t *) malloc (sizeof (pthread_t));   //创建线程id

    return queue;
}
/** 
  * uart发送初始化
  * 
  * 返回值：工作队列结构体指针
  **/
Cthread_uartworkqueue *uartworkqueue_init()
{
    Cthread_uartworkqueue *queue = (Cthread_uartworkqueue *) malloc (sizeof (Cthread_uartworkqueue)); //为工作队列分配内存
    pthread_mutex_init (&(queue->queue_lock), NULL);             //初始化互斥锁
    pthread_cond_init (&(queue->queue_ready), NULL);             //初始化条件变量
    queue->queue_head = NULL;                                    //初始化工作队列头
    queue->cur_queue_size = 0;
    queue->queuethreadid =(pthread_t *) malloc (sizeof (pthread_t));   //创建线程id

    return queue;
}

/** 
  * tcp发送初始化
  * 
  * 返回值：工作队列结构体指针
  **/
Cthread_ethworkqueue *ethworkqueue_init()
{

    Cthread_ethworkqueue *queue = (Cthread_ethworkqueue *) malloc (sizeof (Cthread_ethworkqueue)); //为工作队列分配内存
    pthread_mutex_init (&(queue->queue_lock), NULL);             //初始化互斥锁
    pthread_cond_init (&(queue->queue_ready), NULL);             //初始化条件变量
    queue->queue_head = NULL;                                    //初始化工作队列头
    queue->cur_queue_size = 0;
    queue->queuethreadid =(pthread_t *) malloc (sizeof (pthread_t));   //创建线程id

    return queue;
}


/** 
  * UDP发送初始化
  * 
  * 返回值：工作队列结构体指针
  **/
Cthread_udpworkqueue *udpworkqueue_init()
{

    Cthread_udpworkqueue *queue = (Cthread_udpworkqueue *) malloc (sizeof (Cthread_udpworkqueue)); //为工作队列分配内存
    pthread_mutex_init (&(queue->queue_lock), NULL);             //初始化互斥锁
    pthread_cond_init (&(queue->queue_ready), NULL);             //初始化条件变量
    queue->queue_head = NULL;                                    //初始化工作队列头
    queue->cur_queue_size = 0;
    queue->queuethreadid =(pthread_t *) malloc (sizeof (pthread_t));   //创建线程id

    return queue;
}


void queue_init(void)
{
    cansendqueue = (Cthread_canworkqueue *)canworkqueue_init();         //实例化can发送工作队列
    uartsendqueue = (Cthread_uartworkqueue *)uartworkqueue_init();      //实例化uart发送队列
    ethsendqueue = (Cthread_ethworkqueue *)ethworkqueue_init();         //实例化tcp发送队列
    udpsendqueue = (Cthread_udpworkqueue *)udpworkqueue_init();         //实例化udp发送队列

    canrecvqueue = (Cthread_canworkqueue *)canworkqueue_init();         //实例化can接收工作队列
    ethrecvqueue = (Cthread_ethworkqueue *)ethworkqueue_init();         //实例化tcp接收队列
    uartrecvqueue = (Cthread_uartworkqueue *)uartworkqueue_init();      //实例化uart接收队列
}

